/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * This file is part of Harmattan SmashMiner OpenGL game application.
 * 
 * Harmattan SmashMiner OpenGL Example Application version 1.0.0
 *  
 * Latest update: 15.4.2011
 *
 * The Harmattan SmashMiner OpenGL example application demonstrates how to use 
 * the OpenGL ES in Harmattan devices.
 *
 * This example is provided as a starting point for 3rd party
 * developers (you) to ease the implementation of OpenGL based 
 * games. Ideas, parts of code or methodologies that this
 * example application uses can be freely used without restrictions.
 *
 * See file README.txt how to build and compile this example application
 * in the Harmattan SDK environment. 
 * 
 * See file INSTALL.txt to find out what is required to run this
 * application and how to install the application to the device or
 * alternatively in QEMU-emulator.
 *
 * The LICENSE.txt file explains the license this software is provided
 * with. A copy of the same license is included in this source file.
 * 
 */

/*
 * Copyright (C) 2011 by Nokia Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "gametimer.h"

#include "qdebug.h"

/*!
 * \class GameTimer
 * \brief \c GameTimer is used for instantiating game timers for animation, effects, game state handling, etc.  

  The base class for timers is \c GameTimer class. \c GameTimer class is used mostly as is 
  to instantiate timers in \c TimerManager. The enumeration type \c TimerType enumerates 
  all the timers used in SmashMiner. There are game state timers (\c stateGetReadyTimer, 
  \c stateLevelChangingTimer, \c statePlayerCrashedTimer and \c stateGameOverTimer), 
  space ship timers (\c shipSafeTimer, \c shipBall2ConeTimer and \c shipCone2BallTimer), 
  effect timers (\c hyperJumpOutTimer, \c hyperJumpInTimer and \c bombEffectTimer) and 
  a timer for populating objects to game (\c moreObjectsTimer). Game timer stores current time, 
  full time, half time and quarter time values and provides methods for starting and stopping 
  the timer and quering the timer state: is timer active or is a certain time point 
  (full time, half time, first/last quarter time) reached.
  
  Specified timers expanded from \c GameTimer also store other data related to action related to specific timer. \c LocationTimer stores x- and y-locations. \c BombTimer expanded from \c LocationTimer stores also radiuses for ''shock wave'' and light effects.

*/


/*!
  \brief Constructor of \c GameTimer class.  

  \param type       One of the \c GameTimer::TimerType enumeration values describing the type of timer being instantiated.
  \param endTime    The timer end time, when reached \c isFullTime() returns true.
  \param parent     The parent of a timer is an instance of \c TimerManager. 
*/
GameTimer::GameTimer(TimerType type, int endTime, QObject *parent) 
    : QObject(parent)
    , timerType(type)
    , currentTime(-1)
    , firstQuarterTime(endTime / 4)
    , halfTime(firstQuarterTime * 2)
    , lastQuarterTime(firstQuarterTime * 3)
    , fullTime(endTime)
    , firstQuarterTimeReplied(false)
    , halfTimeReplied(false)
    , lastQuarterTimeReplied(false)
    , fullTimeReplied(false)
{
}

/*! Starts the timer from optional start time. If start time is not provided starts the timer from
 * 0.
 * 
 * \param startTime Start time of the timer
 */
void GameTimer::start(int startTime)
{
#ifdef SMASHMINER_CONFIG_ENABLE_DEBUG_CHECKS

    if (startTime < 0) 
        qFatal("GameTimer::start() : startTime is negative.");

#endif  // SMASHMINER_CONFIG_ENABLE_DEBUG_CHECKS

    currentTime = startTime;

    firstQuarterTimeReplied = false;
    halfTimeReplied = false;
    lastQuarterTimeReplied = false;
    fullTimeReplied = false;
}

/*! Stops the timer
 */
void GameTimer::stop()
{
    currentTime = -1;

    firstQuarterTimeReplied = false;
    halfTimeReplied = false;
    lastQuarterTimeReplied = false;
    fullTimeReplied = false;
}

/*! For querying if timer is active.
 * \return Returns true if timer is started but end time is not yet reached.
 */
bool GameTimer::isActive() const
{
    if (currentTime < 0 || currentTime > fullTime)
        return false;
    else
        return true;
}

/*! For querying if the first quarter time is reached. 
 * Note: This is works as a ''one-shot'' method for each timer run. When the first
 * quarter time has been reached, true will be returned only the first time asked.
 *
 * \return Returns true once when the first quarter time has passed
 */
bool GameTimer::isFirstQuarterTime()
{
    if (firstQuarterTimeReplied)
        return false;

    if (currentTime > firstQuarterTime) {
        firstQuarterTimeReplied = true;
        return true;
    }
    else
        return false;
}

/*! For querying if the half time is reached. 
 * Note: This is works as a ''one-shot'' method for each timer run. When the 
 * half time has been reached, true will be returned only the first time asked.
 *
 * \return Returns true once when the half time has passed
 */
bool GameTimer::isHalfTime()
{
    if (halfTimeReplied)
        return false;

    if (currentTime > halfTime) {
        halfTimeReplied = true;
        return true;
    }
    else
        return false;
}

/*! For querying if the last quarter time is reached. 
 * Note: This is works as a ''one-shot'' method for each timer run. When the last 
 * quarter time has been reached, true will be returned only the first time asked.
 *
 * \return Returns true once when the last quarter time has passed
 */
bool GameTimer::isLastQuarterTime()
{
    if (lastQuarterTimeReplied)
        return false;

    if (currentTime > lastQuarterTime) {
        lastQuarterTimeReplied = true;
        return true;
    } else {
        return false;
    }
}

/*! For querying if the full time is reached. 
 * Note: This is works as a ''one-shot'' method for each timer run. When the 
 * full time has been reached, true will be returned only the first time asked.
 *
 * \return Returns true once when the full time has passed
 */
bool GameTimer::isFullTime()
{
    if (fullTimeReplied)
        return false;

    if (currentTime > fullTime) {
        fullTimeReplied = true;
        return true;
    } else {
        return false;
    }
}

/*! Increases the timer with given time step.
 *
 * \param timeStep Time step used for increasing the timer in milliseconds. 
 */
void GameTimer::incTime(int timeStep)
{
#ifdef SMASHMINER_CONFIG_ENABLE_DEBUG_CHECKS

    if (timeStep < 0)
        qFatal("GameTimer::incTime() : timeStep is negative.");

#endif  // SMASHMINER_CONFIG_ENABLE_DEBUG_CHECKS

    if (currentTime < 0 || currentTime > fullTime)
        return;

    currentTime += timeStep;
}
